package cn.iocoder.yudao.framework.mybatis.interceptor;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.extra.tokenizer.Result;
import cn.hutool.json.JSONUtil;
import cn.iocoder.yudao.framework.datasource.local.TenantLocalContext;
import cn.iocoder.yudao.framework.datasource.local.ThreadLocalContext;
import cn.iocoder.yudao.framework.datasource.properties.TenantProperties;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.github.xiaoymin.knife4j.core.util.CommonUtils;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.PrintWriter;

/**
 * TODO
 *
 * @className: TenantInterceptor
 * @author: tangkh
 * @date: 2023-09-19 17:34
 */
public class TenantInterceptor implements HandlerInterceptor {
    private TenantProperties tenantProperties;

    @Override
    public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {
        try {
            Long orgId = null;
            HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
            String selOrgId = null;//todo CommonUtils.getSelOrgId(request);
            if (StringUtils.isNotBlank(selOrgId)) {
                orgId = Long.valueOf(selOrgId);
            } else {
                String gwOrgId = request.getParameter("gwOrgId");
                if (StringUtils.isNotEmpty(gwOrgId)) {
                    orgId = Long.valueOf(gwOrgId);
                }
            }

            if (orgId == null) {
                boolean flag = this.checkExcludePath(httpServletRequest);
                if (flag) {
                    return flag;
                } else {
                   // this.renderContentJSON(httpServletResponse, ErrorCommonConstant.SERVICE_EXCEPTION.getCode(), "租户id不能为空");
                    return false;
                }
            } else {
                TenantLocalContext.setTenantId(orgId);
                this.checkExcludePath(httpServletRequest);
                return true;
            }
        } catch (Exception e1) { //todo BusinessException
          //  this.renderContentJSON(httpServletResponse, var8.getErrorCode(), var8.getErrorMsg());
            return false;
        }/* catch (Exception e2) {
          //  this.renderContentJSON(httpServletResponse, ErrorCommonConstant.SERVICE_EXCEPTION.getCode(), StringUtils.isNotBlank(var9.getMessage()) ? var9.getMessage() : ErrorCommonConstant.SERVICE_EXCEPTION.getMsg());
            return false;
        }*/
    }

    private boolean checkExcludePath(HttpServletRequest httpServletRequest) {
        if (this.tenantProperties != null && !CollectionUtil.isEmpty(this.tenantProperties.getExcludes())) {
            boolean flag = this.tenantProperties.getExcludes().stream().anyMatch((item) -> {
                return httpServletRequest.getRequestURI().contains(item);
            });
            if (flag) {
                ThreadLocalContext.setAttachment("requestURI", httpServletRequest.getRequestURI());
                return flag;
            } else {
                return false;
            }
        } else {
            return false;
        }
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        TenantLocalContext.clearTenantId();
    }

    private void renderContentJSON(HttpServletResponse httpServletResponse, String code, String msg) throws Exception {
        httpServletResponse.setContentType("application/json; charset=UTF-8");
        httpServletResponse.setCharacterEncoding("UTF-8");
        PrintWriter write = httpServletResponse.getWriter();
       // Result result = ResultMessage.failure(code, msg, (Object)null);
        //write.write(JSONUtil.toJsonStr(result));
        write.flush();
        write.close();
    }

    public TenantInterceptor() {
    }

    public TenantInterceptor(TenantProperties tenantProperties) {
        this.tenantProperties = tenantProperties;
    }
}
